home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / host contacted / jikes.lha / jikes-1.11 / src / symbol.cpp < prev    next >
C/C++ Source or Header  |  2000-01-16  |  71KB  |  1,926 lines

  1. // $Id: symbol.cpp,v 1.32 2000/01/06 08:24:30 lord Exp $
  2. //
  3. // This software is subject to the terms of the IBM Jikes Compiler Open
  4. // Source License Agreement available at the following URL:
  5. // http://www.ibm.com/research/jikes.
  6. // Copyright (C) 1996, 1998, International Business Machines Corporation
  7. // and others.  All Rights Reserved.
  8. // You must accept the terms of that agreement to use this software.
  9. //
  10. #include "config.h"
  11. #include <sys/stat.h>
  12. #include <assert.h>
  13. #include "stream.h"
  14. #include "control.h"
  15. #include "ast.h"
  16. #include "semantic.h"
  17. #include "table.h"
  18. #include "zip.h"
  19. #include "set.h"
  20. #include "case.h"
  21.  
  22. #if defined(UNIX_FILE_SYSTEM) || defined(AMIGAOS_FILE_SYSTEM)
  23. #include <dirent.h>
  24. #elif defined(WIN32_FILE_SYSTEM)
  25. #include <windows.h>
  26. #endif
  27.  
  28. char *FileSymbol::java_suffix = StringConstant::U8S__DO_java;
  29. int FileSymbol::java_suffix_length = strlen(java_suffix);
  30. char *FileSymbol::class_suffix = StringConstant::U8S__DO_class;
  31. int FileSymbol::class_suffix_length = strlen(class_suffix);
  32.  
  33. bool MethodSymbol::IsFinal()
  34. {
  35.     return ((AccessFlags *) this) -> ACC_FINAL() || ((AccessFlags *) this) -> ACC_PRIVATE() || containing_type -> ACC_FINAL();
  36. }
  37.  
  38. wchar_t *MethodSymbol::Header()
  39. {
  40.     assert(type_);
  41.  
  42.     if (! header)
  43.     {
  44.         bool is_constructor = false;
  45.         for (MethodSymbol *constr = containing_type -> FindConstructorSymbol(); constr; constr = constr -> next_method)
  46.         {
  47.             if (this == constr)
  48.             {
  49.                 is_constructor = true;
  50.                 break;
  51.             }
  52.         }
  53.  
  54.         int length = this -> Type() -> ContainingPackage() -> PackageNameLength() +
  55.                      this -> Type() -> ExternalNameLength() +
  56.                      (is_constructor ? containing_type -> NameLength() : this -> NameLength()) + 5; // '/' after package_name
  57.                                                                                                     // ' ' after type
  58.                                                                                                     // '(' after name
  59.                                                                                                     // ')' after all parameters
  60.                                                                                                     // ';' to terminate
  61.         for (int i = 0; i < NumFormalParameters(); i++)
  62.         {
  63.             VariableSymbol *formal = FormalParameter(i);
  64.             length += (formal -> Type() -> ContainingPackage() -> PackageNameLength() +
  65.                        formal -> Type() -> ExternalNameLength() +
  66.                        formal -> NameLength() + 4); // '/' after package_name
  67.                                                     // ' ' after type
  68.                                                     // ',' and ' ' to separate this formal parameter from the next one
  69.         }
  70.  
  71.         header = new wchar_t[length + 1]; // +1 for '\0'
  72.         wchar_t *s = header;
  73.  
  74.         if (is_constructor)
  75.         {
  76.             for (wchar_t *s2 = this -> containing_type -> Name(); *s2; s2++)
  77.                  *s++ = *s2;
  78.         }
  79.         else
  80.         {
  81.             PackageSymbol *package = this -> Type() -> ContainingPackage();
  82.             wchar_t *package_name = package -> PackageName();
  83.             if (package -> PackageNameLength() > 0 && wcscmp(package_name, StringConstant::US__DO) != 0)
  84.             {
  85.                 while (*package_name)
  86.                 {
  87.                     *s++ = (*package_name == U_SLASH ? (wchar_t) U_DOT : *package_name);
  88.                     package_name++;
  89.                 }
  90.                 *s++ = U_DOT;
  91.             }
  92.  
  93.             for (wchar_t *s2 = this -> Type() -> ExternalName(); *s2; s2++)
  94.                  *s++ = *s2;
  95.             *s++ = U_SPACE;
  96.             for (wchar_t *s3 = Name(); *s3; s3++)
  97.                  *s++ = *s3;
  98.         }
  99.         *s++ = U_LEFT_PARENTHESIS;
  100.         if (NumFormalParameters() > 0)
  101.         {
  102.             for (int k = 0; k < NumFormalParameters(); k++)
  103.             {
  104.                 VariableSymbol *formal = FormalParameter(k);
  105.  
  106.                 PackageSymbol *package = formal -> Type() -> ContainingPackage();
  107.                 wchar_t *package_name = package -> PackageName();
  108.                 if (package -> PackageNameLength() > 0 && wcscmp(package_name, StringConstant::US__DO) != 0)
  109.                 {
  110.                     while (*package_name)
  111.                     {
  112.                         *s++ = (*package_name == U_SLASH ? (wchar_t) U_DOT : *package_name);
  113.                         package_name++;
  114.                     }
  115.                     *s++ = U_DOT;
  116.                 }
  117.  
  118.                 for (wchar_t *s2 = formal -> Type() -> ExternalName(); *s2; s2++)
  119.                     *s++ = *s2;
  120.                 *s++ = U_SPACE;
  121.                 for (wchar_t *s3 = formal -> Name(); *s3; s3++)
  122.                      *s++ = *s3;
  123.                 *s++ = U_COMMA;
  124.                 *s++ = U_SPACE;
  125.             }
  126.  
  127.             s -= 2; // remove the last ',' and ' '
  128.         }
  129.         *s++ = U_RIGHT_PARENTHESIS;
  130.         *s++ = U_SEMICOLON;
  131.         *s = U_NULL;
  132.  
  133.         assert((s - header) <= length);
  134.     }
  135.  
  136.     return header;
  137. }
  138.  
  139.  
  140. MethodSymbol *SymbolTable::FindOverloadMethod(MethodSymbol *base_method, AstMethodDeclarator *method_declarator)
  141. {
  142.     for (MethodSymbol *method = base_method; method; method = method -> next_method)
  143.     {
  144.         assert(method -> IsTyped());
  145.  
  146.         if (method -> NumFormalParameters() == method_declarator -> NumFormalParameters())
  147.         {
  148.             int i;
  149.             for (i = method -> NumFormalParameters() - 1; i >= 0; i--)
  150.             {
  151.                 AstFormalParameter *parameter = method_declarator -> FormalParameter(i);
  152.                 if (method -> FormalParameter(i) -> Type() != parameter -> formal_declarator -> symbol -> Type())
  153.                     break;
  154.             }
  155.             if (i < 0)
  156.                 return method;
  157.         }
  158.     }
  159.  
  160.     return(MethodSymbol *)  NULL;
  161. }
  162.  
  163.  
  164. void TypeSymbol::ProcessTypeHeaders()
  165. {
  166.     AstClassDeclaration *class_declaration = declaration -> ClassDeclarationCast();
  167.  
  168.     if (class_declaration)
  169.          semantic_environment -> sem -> ProcessTypeHeaders(class_declaration);
  170.     else semantic_environment -> sem -> ProcessTypeHeaders((AstInterfaceDeclaration *) declaration);
  171. }
  172.  
  173. void TypeSymbol::ProcessMembers()
  174. {
  175.     AstClassDeclaration *class_declaration = declaration -> ClassDeclarationCast();
  176.  
  177.     if (class_declaration)
  178.          semantic_environment -> sem -> ProcessMembers(class_declaration -> semantic_environment, class_declaration -> class_body);
  179.     else semantic_environment -> sem -> ProcessMembers((AstInterfaceDeclaration *) declaration);
  180. }
  181.  
  182. void TypeSymbol::CompleteSymbolTable()
  183. {
  184.     AstClassDeclaration *class_declaration = declaration -> ClassDeclarationCast();
  185.  
  186.     if (class_declaration)
  187.          semantic_environment -> sem -> CompleteSymbolTable(class_declaration -> semantic_environment,
  188.                                                             class_declaration -> identifier_token, class_declaration -> class_body);
  189.     else semantic_environment -> sem -> CompleteSymbolTable((AstInterfaceDeclaration *) declaration);
  190. }
  191.  
  192.  
  193. void TypeSymbol::ProcessExecutableBodies()
  194. {
  195.     AstClassDeclaration *class_declaration = declaration -> ClassDeclarationCast();
  196.  
  197.     if (class_declaration)
  198.          semantic_environment -> sem -> ProcessExecutableBodies(class_declaration -> semantic_environment,
  199.                                                                 class_declaration -> class_body);
  200.     else semantic_environment -> sem -> ProcessExecutableBodies((AstInterfaceDeclaration *) declaration);
  201. }
  202.  
  203.  
  204. void TypeSymbol::RemoveCompilationReferences()
  205. {
  206.     if (semantic_environment)
  207.     {
  208.         semantic_environment = NULL;
  209.         declaration = NULL;
  210.  
  211.         //
  212.         // TODO: What else needs to be reset?
  213.         //
  214.         if (table)
  215.         {
  216.             for (int i = 0; i < table -> NumVariableSymbols(); i++)
  217.                 table -> VariableSym(i) -> declarator = NULL;
  218.  
  219.             for (int j = 0; j < table -> NumMethodSymbols(); j++)
  220.                 table -> MethodSym(j) -> method_or_constructor_declaration = NULL;
  221.  
  222.             for (int k = 0; k < table -> NumTypeSymbols(); k++)
  223.                 table -> TypeSym(k) -> declaration = NULL;
  224.  
  225.             for (int l = 0; l < table -> NumAnonymousSymbols(); l++)
  226.                 table -> AnonymousSym(l) -> declaration = NULL;
  227.         }
  228.     }
  229.  
  230.     return;
  231. }
  232.  
  233.  
  234. TypeSymbol *TypeSymbol::GetArrayType(Semantic *sem, int num_dimensions_)
  235. {
  236.     if (num_dimensions_ == 0)
  237.         return this;
  238.     if (num_dimensions_ < NumArrays())
  239.         return Array(num_dimensions_);
  240.  
  241.     if (NumArrays() == 0)
  242.         AddArrayType(this);
  243.  
  244.     TypeSymbol *previous_array_type = Array(array -> Length() - 1);
  245.     wchar_t *name = new wchar_t[this -> ExternalNameLength() + (num_dimensions_ * 2) + 1];
  246.     wcscpy(name, previous_array_type -> ExternalName());
  247.  
  248.     for (int num = array -> Length(), len = previous_array_type -> ExternalNameLength() + 2;
  249.          num <= num_dimensions_;
  250.          num++, len = len + 2)
  251.     {
  252.         wcscat(name, StringConstant::US__LB__RB);
  253.         NameSymbol *name_sym = sem -> control.FindOrInsertName(name, len);
  254.  
  255.         TypeSymbol *type = new TypeSymbol(name_sym);
  256.  
  257.         type -> MarkHeaderProcessed();
  258.         type -> MarkConstructorMembersProcessed();
  259.         type -> MarkMethodMembersProcessed();
  260.         type -> MarkFieldMembersProcessed();
  261.         type -> MarkLocalClassProcessingCompleted();
  262.         type -> MarkSourceNoLongerPending();
  263.         type -> outermost_type = type;
  264.  
  265.         type -> SetACC_PUBLIC();
  266.         type -> SetACC_FINAL();
  267.  
  268.         type -> super = sem -> control.Object();
  269.         //
  270.         // All arrays implement the interfaces java.io.Serializable and
  271.         // java.io.Cloneable
  272.         //
  273.         type -> AddInterface(sem -> control.Serializable());
  274.         type -> AddInterface(sem -> control.Cloneable());
  275.         type -> base_type = this;
  276.         type -> num_dimensions = num;
  277.         type -> SetOwner(this -> ContainingPackage());
  278.         type -> table = new SymbolTable(3); // only 2 elements will be added to this table
  279.         type -> SetSignature(sem -> control);
  280.  
  281.         MethodSymbol *method = type -> InsertMethodSymbol(sem -> control.clone_name_symbol);
  282.         method -> SetType(sem -> control.Object());
  283.         method -> SetContainingType(type);
  284.         method -> SetACC_PUBLIC();
  285.         method -> SetACC_FINAL();
  286.         method -> SetBlockSymbol(new BlockSymbol(1)); // the associated symbol table will remain empty
  287.         method -> SetSignature(sem -> control);
  288.  
  289.         VariableSymbol *symbol = type -> InsertVariableSymbol(sem -> control.length_name_symbol);
  290.         symbol -> SetACC_PUBLIC();
  291.         symbol -> SetACC_FINAL();
  292.         symbol -> SetOwner(type);
  293.         symbol -> SetType(sem -> control.int_type);
  294.  
  295.         type -> CompressSpace(); // space optimization
  296.  
  297.         AddArrayType(type);
  298.     }
  299.  
  300.     delete [] name;
  301.     return Array(num_dimensions_);
  302. }
  303.  
  304. void TypeSymbol::SetLocation()
  305. {
  306.     if (! declaration)
  307.         file_location = new FileLocation(file_symbol);
  308.     else
  309.     {
  310.         AstClassDeclaration *class_declaration = declaration -> ClassDeclarationCast();
  311.         AstInterfaceDeclaration *interface_declaration = declaration -> InterfaceDeclarationCast();
  312.  
  313.         file_location = new FileLocation(semantic_environment -> sem -> lex_stream,
  314.                                          (class_declaration
  315.                                                ? class_declaration -> identifier_token
  316.                                                : (interface_declaration
  317.                                                            ? interface_declaration -> identifier_token
  318.                                                            : ((AstClassInstanceCreationExpression *) declaration)
  319.                                                                                            -> class_body_opt -> left_brace_token)));
  320.     }
  321.  
  322.     return;
  323. }
  324.  
  325.  
  326. void TypeSymbol::SetSignature(Control &control)
  327. {
  328.     if (this -> num_dimensions > 0)
  329.     {
  330.         char *type_signature;
  331.         TypeSymbol *subtype = this -> ArraySubtype();
  332.         int signature_len = strlen(subtype -> SignatureString()) + 1; // +1 for '['
  333.         type_signature = new char[signature_len + 1];                  // +1 for '\0'
  334.         type_signature[0] = U_LEFT_BRACKET;
  335.         strcpy(type_signature + 1, subtype -> SignatureString());
  336.         this -> signature = control.Utf8_pool.FindOrInsert(type_signature, signature_len);
  337.         this -> fully_qualified_name = this -> signature;
  338.         delete [] type_signature;
  339.     }
  340.     else
  341.     {
  342.         wchar_t *package_name = this -> ContainingPackage() -> PackageName();
  343.         wchar_t *type_name = this -> ExternalName();
  344.  
  345.         int len = this -> ContainingPackage() -> PackageNameLength() +
  346.                   this -> ExternalNameLength() + 4; // +1 for 'L' +1 for '/' +1 for ';' +1 for '\0'
  347.         wchar_t *type_signature = new wchar_t[len];
  348.         wcscpy(type_signature, StringConstant::US_L);
  349.         if (this -> ContainingPackage() -> PackageNameLength() > 0 && wcscmp(package_name, StringConstant::US__DO) != 0)
  350.         {
  351.             wcscat(type_signature, package_name);
  352.             wcscat(type_signature, StringConstant::US__SL);
  353.         }
  354.         wcscat(type_signature, type_name);
  355.         this -> fully_qualified_name = control.ConvertUnicodeToUtf8(type_signature + 1); // +1 to skip the initial L'L'
  356.  
  357.         wcscat(type_signature, StringConstant::US__SC);
  358.         this -> signature = control.ConvertUnicodeToUtf8(type_signature);
  359.  
  360.         delete [] type_signature;
  361.  
  362.         if (! (this -> Anonymous() || this -> IsLocal()))
  363.             control.type_table.InsertType((TypeSymbol *) this);
  364.     }
  365.  
  366.     return;
  367. }
  368.  
  369.  
  370. int SymbolTable::primes[] = {DEFAULT_HASH_SIZE, 101, 401, MAX_HASH_SIZE};
  371.  
  372. void SymbolTable::Rehash()
  373. {
  374.     hash_size = primes[++prime_index];
  375.  
  376.     delete [] base;
  377.     base = (Symbol **) memset(new Symbol *[hash_size], 0, hash_size * sizeof(Symbol *));
  378.  
  379.     int k;
  380.     for (k = 0; k < NumTypeSymbols(); k++)
  381.     {
  382.         TypeSymbol *symbol = TypeSym(k);
  383.         int i = symbol -> name_symbol -> index % hash_size;
  384.         symbol -> next = base[i];
  385.         base[i] = symbol;
  386.     }
  387.  
  388.     for (k = 0; k < NumMethodSymbols(); k++)
  389.     {
  390.         MethodSymbol *symbol = MethodSym(k);
  391.         if (symbol -> next != symbol) // not an overload
  392.         {
  393.             int i = symbol -> name_symbol -> index % hash_size;
  394.             symbol -> next = base[i];
  395.             base[i] = symbol;
  396.         }
  397.     }
  398.  
  399.     for (k = 0; k < NumVariableSymbols(); k++)
  400.     {
  401.         VariableSymbol *symbol = VariableSym(k);
  402.         int i = symbol -> name_symbol -> index % hash_size;
  403.         symbol -> next = base[i];
  404.         base[i] = symbol;
  405.     }
  406.  
  407.     for (k = 0; k < NumOtherSymbols(); k++)
  408.     {
  409.         Symbol *symbol = OtherSym(k);
  410.  
  411.         if (! symbol -> BlockCast())
  412.         {
  413.             int i = symbol -> Identity() -> index % hash_size;
  414.             symbol -> next = base[i];
  415.             base[i] = symbol;
  416.         }
  417.     }
  418.  
  419.     return;
  420. }
  421.  
  422.  
  423. SymbolTable::SymbolTable(int hash_size_) : type_symbol_pool(NULL),
  424.                                            anonymous_symbol_pool(NULL),
  425.                                            method_symbol_pool(NULL),
  426.                                            variable_symbol_pool(NULL),
  427.                                            other_symbol_pool(NULL),
  428.                                            constructor(NULL)
  429. {
  430.     hash_size = (hash_size_ <= 0 ? 1 : hash_size_);
  431.  
  432.     prime_index = -1;
  433.     do
  434.     {
  435.         if (hash_size < primes[prime_index + 1])
  436.             break;
  437.         prime_index++;
  438.     } while (primes[prime_index] < MAX_HASH_SIZE);
  439.  
  440.     base = (Symbol **) memset(new Symbol *[hash_size], 0, hash_size * sizeof(Symbol *));
  441. }
  442.  
  443. SymbolTable::~SymbolTable()
  444. {
  445. /*
  446. int n;
  447. int num_slots = 0;
  448. int total = 0;
  449. for (n = 0; n < hash_size; n++)
  450. {
  451. int num = 0;
  452. for (Symbol *s = base[n]; s; s = s -> next)
  453.     num++;
  454. if (num > 0)
  455. {
  456. num_slots++;
  457. total += num;
  458. }
  459. }
  460.  
  461. if (num_slots > 0)
  462. {
  463. cout << "\nDestroying a symbol table with base size " << hash_size << " containing " << num_slots << " non-empty slots\n";
  464. for (n = 0; n < hash_size; n++)
  465. {
  466. int num = 0;
  467. for (Symbol *s = base[n]; s; s = s -> next)
  468.     num++;
  469. if (num > 0)
  470. cout << "    slot " << n << " contains " << num << " element(s)\n";
  471. }
  472. }
  473. if (hash_size < total)
  474.     total = total;
  475. */
  476.     for (int i = 0; i < NumAnonymousSymbols(); i++)
  477.         delete AnonymousSym(i);
  478.     delete anonymous_symbol_pool;
  479.     for (int j = 0; j < NumTypeSymbols(); j++)
  480.         delete TypeSym(j);
  481.     delete type_symbol_pool;
  482.     for (int k = 0; k < NumMethodSymbols(); k++)
  483.         delete MethodSym(k);
  484.     delete method_symbol_pool;
  485.     for (int l = 0; l < NumVariableSymbols(); l++)
  486.         delete VariableSym(l);
  487.     delete variable_symbol_pool;
  488.     for (int m = 0; m < NumOtherSymbols(); m++)
  489.         delete OtherSym(m);
  490.     delete other_symbol_pool;
  491.     delete [] base;
  492.  
  493.     return;
  494. }
  495.  
  496.  
  497. PackageSymbol::~PackageSymbol()
  498. {
  499.     delete [] package_name;
  500.     delete table;
  501. }
  502.  
  503.  
  504. void PackageSymbol::SetPackageName()
  505. {
  506.     this -> package_name_length = (owner ? owner -> PackageNameLength() + 1 : 0) + NameLength(); // +1 for '/'
  507.     this -> package_name = new wchar_t[package_name_length + 1]; // +1 for '\0'
  508.  
  509.     if (owner)
  510.     {
  511.         wcscpy(this -> package_name, owner -> PackageName());
  512.         wcscat(this -> package_name, StringConstant::US__SL);
  513.     }
  514.     else this -> package_name[0] = U_NULL;
  515.     wcscat(this -> package_name, this -> Name());
  516.  
  517.     assert(wcslen(this -> package_name) == this -> package_name_length);
  518.  
  519.     return;
  520. }
  521.  
  522.  
  523. TypeSymbol::TypeSymbol(NameSymbol *name_symbol_) : semantic_environment(NULL),
  524.                                                    declaration(NULL),
  525.                                                    file_symbol(NULL),
  526.                                                    file_location(NULL),
  527.                                                    name_symbol(name_symbol_),
  528.                                                    owner(NULL),
  529.                                                    outermost_type(NULL),
  530.                                                    super(NULL),
  531.                                                    base_type(NULL),
  532.                                                    index(CycleChecker::OMEGA),
  533.                                                    unit_index(CycleChecker::OMEGA),
  534.                                                    incremental_index(CycleChecker::OMEGA),
  535.                                                    local(NULL),
  536.                                                    non_local(NULL),
  537.                                                    supertypes_closure(NULL),
  538.                                                    subtypes(NULL),
  539.                                                    subtypes_closure(NULL),
  540.                                                    innertypes_closure(NULL),
  541.                                                    dependents(new SymbolSet()),
  542.                                                    parents(new SymbolSet()),
  543.                                                    static_parents(new SymbolSet()),
  544.                                                    dependents_closure(NULL),
  545.                                                    parents_closure(NULL),
  546.                                                    signature(NULL),
  547.                                                    fully_qualified_name(NULL),
  548.                                                    expanded_type_table(NULL),
  549.                                                    expanded_field_table(NULL),
  550.                                                    expanded_method_table(NULL),
  551.                                                    num_dimensions(0),
  552.                                                    static_initializer_method(NULL),
  553.                                                    block_initializer_method(NULL),
  554.                                                    external_name_symbol(NULL),
  555.                                                    table(NULL),
  556.                                                    local_shadow_map(NULL),
  557.                                                    status(0),
  558.                                                    package(NULL),
  559.                                                    class_name(NULL),
  560.                                                    class_literal_class(NULL),
  561.                                                    class_literal_method(NULL),
  562.                                                    class_literal_name(NULL),
  563.                                                    local_constructor_call_environments(NULL),
  564.                                                    private_access_methods(NULL),
  565.                                                    private_access_constructors(NULL),
  566.                                                    read_method(NULL),
  567.                                                    write_method(NULL),
  568.                                                    constructor_parameters(NULL),
  569.                                                    generated_constructors(NULL),
  570.                                                    enclosing_instances(NULL),
  571.                                                    class_literals(NULL),
  572.                                                    nested_type_signatures(NULL),
  573.                                                    nested_types(NULL),
  574.                                                    interfaces(NULL),
  575.                                                    anonymous_types(NULL),
  576.                                                    array(NULL)
  577. {
  578.     Symbol::_kind = TYPE;
  579. }
  580.  
  581.  
  582. TypeSymbol::~TypeSymbol()
  583. {
  584.     delete semantic_environment;
  585.     delete local;
  586.     delete non_local;
  587.     delete supertypes_closure;
  588.     delete subtypes;
  589.     delete subtypes_closure;
  590.     delete innertypes_closure;
  591.     delete dependents;
  592.     delete parents;
  593.     delete static_parents;
  594.     delete table;
  595.     delete local_shadow_map;
  596.     delete expanded_type_table;
  597.     delete expanded_field_table;
  598.     delete expanded_method_table;
  599.     delete file_location;
  600.     delete [] class_name;
  601.     for (int i = 1; i < NumArrays(); i++)
  602.         delete Array(i);
  603.     for (int k = 0; k < NumNestedTypeSignatures(); k++)
  604.         delete [] NestedTypeSignature(k);
  605.     delete nested_type_signatures;
  606.  
  607.     delete local_constructor_call_environments;
  608.     delete private_access_methods;
  609.     delete private_access_constructors;
  610.     delete constructor_parameters;
  611.     delete generated_constructors;
  612.     delete enclosing_instances;
  613.     delete class_literals;
  614.     delete nested_types;
  615.     delete interfaces;
  616.     delete anonymous_types;
  617.     delete array;
  618. }
  619.  
  620. MethodSymbol::~MethodSymbol()
  621. {
  622.     for (int i = 0; i < NumThrowsSignatures(); i++)
  623.         delete [] ThrowsSignature(i);
  624.     delete throws_signatures;
  625.     delete formal_parameters;
  626.     delete throws;
  627.     delete initializer_constructors;
  628.  
  629.     delete block_symbol; // overload(s)
  630.     delete [] header;
  631. }
  632.  
  633.  
  634. BlockSymbol::BlockSymbol(int hash_size) : max_variable_index(-1),
  635.                                           try_or_synchronized_variable_index(0),
  636.                                           table(hash_size > 0 ? new SymbolTable(hash_size) : (SymbolTable *) NULL)
  637. {
  638.     Symbol::_kind = BLOCK;
  639. }
  640.  
  641. BlockSymbol::~BlockSymbol()
  642. {
  643.     delete table;
  644. }
  645.  
  646. PathSymbol::PathSymbol(NameSymbol *name_symbol_) : name_symbol(name_symbol_),
  647.                                                    zipfile(NULL)
  648. {
  649.     Symbol::_kind = PATH;
  650. }
  651.  
  652. PathSymbol::~PathSymbol()
  653. {
  654.     if (zipfile)
  655.         delete zipfile;
  656. }
  657.  
  658.  
  659. DirectorySymbol::DirectorySymbol(NameSymbol *name_symbol_, Symbol *owner_) : owner(owner_),
  660.                                                                              name_symbol(name_symbol_),
  661.                                                                              mtime(0),
  662.                                                                              table(NULL),
  663.                                                                              entries(NULL),
  664.                                                                              directory_name(NULL)
  665. {
  666.     Symbol::_kind = _DIRECTORY;
  667. }
  668.  
  669.  
  670. DirectorySymbol::~DirectorySymbol()
  671. {
  672.     delete [] directory_name;
  673.     delete entries;
  674.     delete table;
  675. }
  676.  
  677. void DirectorySymbol::SetDirectoryName()
  678. {
  679.     PathSymbol *path_symbol = owner -> PathCast();
  680.     if (path_symbol)
  681.     {
  682.         if (strcmp(path_symbol -> Utf8Name(), StringConstant::U8S__DO) == 0)
  683.         {
  684.             this -> directory_name_length = this -> Utf8NameLength();
  685.             this -> directory_name = new char[this -> directory_name_length + 1]; // +1 for '\0'
  686.  
  687.             strcpy(this -> directory_name, this -> Utf8Name());
  688.         }
  689.         else
  690.         {
  691.             this -> directory_name_length = path_symbol -> Utf8NameLength();
  692.             this -> directory_name = new char[this -> directory_name_length + 1]; // +1 for '\0'
  693.  
  694.             strcpy(this -> directory_name, path_symbol -> Utf8Name());
  695.         }
  696.     }
  697.     else
  698.     {
  699.         DirectorySymbol *owner_directory = owner -> DirectoryCast();
  700.         if (this -> Name()[this -> NameLength() - 1] == U_SLASH ||                     // An absolute file name ?
  701.             strcmp(owner_directory -> DirectoryName(), StringConstant::U8S__DO) == 0) // or is the owner "." ?
  702.         {
  703.             this -> directory_name_length = this -> Utf8NameLength();
  704.             this -> directory_name = new char[this -> directory_name_length + 1];  // +1 for '\0'
  705.             strcpy(this -> directory_name, this -> Utf8Name());
  706.         }
  707.         else
  708.         {
  709.             int owner_length = owner_directory -> DirectoryNameLength();
  710.             char *owner_name = owner_directory -> DirectoryName();
  711.             this -> directory_name_length = owner_length +
  712.                                             this -> Utf8NameLength() +
  713.                                             (owner_name[owner_length - 1] != U_SLASH ? 1 : 0); // +1 for '/'
  714.  
  715.             this -> directory_name = new char[this -> directory_name_length + 1]; // +1 for '\0'
  716.  
  717.             strcpy(this -> directory_name, owner_directory -> DirectoryName());
  718.             if (owner_name[owner_length - 1] != U_SLASH)
  719.                 strcat(this -> directory_name, StringConstant::U8S__SL);
  720.             strcat(this -> directory_name, this -> Utf8Name());
  721.         }
  722.     }
  723.  
  724.     assert(strlen(this -> directory_name) == this -> directory_name_length);
  725.  
  726.     return;
  727. }
  728.  
  729.  
  730. void DirectorySymbol::ResetDirectory()
  731. {
  732.     //
  733.     // TODO: the stat function does not work for directories in that the "modified" time stamp associated
  734.     // with a directory is not updated when a file contained in the directory is changed.
  735.     // For now, we always reread the directory.
  736.     //
  737.     //    struct stat status;
  738.     //    if ((::SystemStat(this -> DirectoryName(), &status) == 0) && status.st_mtime > mtime)
  739.     //    {
  740.     //        this -> mtime = status.st_mtime;
  741.     //
  742.     //        delete this -> entries;
  743.     //        this -> entries = NULL;
  744.     //    }
  745.     //
  746.     //    ReadDirectory();
  747.     //
  748.  
  749.     delete this -> entries;
  750.     this -> entries = NULL;
  751.  
  752.     ReadDirectory();
  753.  
  754.     return;
  755. }
  756.  
  757.  
  758. void DirectorySymbol::ReadDirectory()
  759. {
  760.     assert(! this -> IsZip());
  761.  
  762.     if (! entries)
  763.     {
  764.         entries = new DirectoryTable();
  765.  
  766. #if defined(UNIX_FILE_SYSTEM) || defined(AMIGAOS_FILE_SYSTEM)
  767.         DIR *directory = opendir(this -> DirectoryName());
  768.         if (directory)
  769.         {
  770.             for (dirent *entry = readdir(directory); entry; entry = readdir(directory))
  771.             {
  772.                 int length = strlen(entry -> d_name);
  773.  
  774.                 //
  775.                 // Check if the file is a java source, a java class file or a subdirectory.
  776.                 // Since packages cannot start with '.', we skip all files that start with
  777.                 // a dot. That includes this directory "." and its parent ".."
  778.                 //
  779.                 if ((length > FileSymbol::java_suffix_length &&
  780.                      FileSymbol::IsJavaSuffix(&entry -> d_name[length - FileSymbol::java_suffix_length]))  ||
  781.                     (length > FileSymbol::class_suffix_length &&
  782.                      FileSymbol::IsClassSuffix(&entry -> d_name[length - FileSymbol::class_suffix_length])) ||
  783.                     ((Case::Index(entry -> d_name, U_DOT) < 0) && SystemIsDirectory(entry -> d_name)))
  784.                     entries -> InsertEntry((DirectorySymbol *) this, entry -> d_name, length);
  785.             }
  786.             closedir(directory);
  787.         }
  788.  
  789. #elif defined(WIN32_FILE_SYSTEM)
  790.  
  791.         char *directory_name = new char[this -> DirectoryNameLength() + 3]; // +2 for "/*" +1 for '\0'
  792.         strcpy(directory_name, this -> DirectoryName());
  793.         if (directory_name[this -> DirectoryNameLength() - 1] != U_SLASH)
  794.             strcat(directory_name, StringConstant::U8S__SL);
  795.         strcat(directory_name, StringConstant::U8S__ST);
  796.  
  797.         WIN32_FIND_DATA entry;
  798.         HANDLE file_handle = FindFirstFile(directory_name, &entry);
  799.         if (file_handle != INVALID_HANDLE_VALUE)
  800.         {
  801.             do
  802.             {
  803.                 int length = strlen(entry.cFileName);
  804.  
  805.                 //
  806.                 // Check if the file is a java source, a java class file or a subdirectory.
  807.                 // Since packages cannot start with '.', we skip all files that start with
  808.                 // a dot. That includes this directory "." and its parent ".."
  809.                 //
  810.                 bool is_java  = (length > FileSymbol::java_suffix_length &&
  811.                                  FileSymbol::IsJavaSuffix(&entry.cFileName[length - FileSymbol::java_suffix_length])),
  812.                      is_class = (length > FileSymbol::class_suffix_length &&
  813.                                  FileSymbol::IsClassSuffix(&entry.cFileName[length - FileSymbol::class_suffix_length]));
  814.  
  815.                 if (is_java ||
  816.                     is_class ||
  817.                     (entry.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY && Case::Index(entry.cFileName, U_DOT) < 0))
  818.                 {
  819.                     char *clean_name = new char[length + 1];
  820.                     for (int i = 0; i < length; i++)
  821.                         clean_name[i] = (entry.cFileName[i] == U_BACKSLASH ? U_SLASH : entry.cFileName[i]);
  822.                     if (is_java)
  823.                          strcpy(&clean_name[length - FileSymbol::java_suffix_length], FileSymbol::java_suffix);
  824.                     else if (is_class)
  825.                          strcpy(&clean_name[length - FileSymbol::class_suffix_length], FileSymbol::class_suffix);
  826.                     DirectoryEntry *entry = entries -> InsertEntry((DirectorySymbol *) this, clean_name, length);
  827.                     if (! is_java)
  828.                         entries -> InsertCaseInsensitiveEntry(entry);
  829.                     delete [] clean_name;
  830.                 }
  831.             } while (FindNextFile(file_handle, &entry));
  832.             FindClose(file_handle);
  833.         }
  834.  
  835.         delete [] directory_name;
  836. #endif
  837.     }
  838.  
  839.     return;
  840. }
  841.  
  842.  
  843. DirectorySymbol *FileSymbol::OutputDirectory()
  844. {
  845.     return (output_directory ? output_directory : output_directory = Control::GetOutputDirectory(this));
  846. }
  847.  
  848.  
  849. void FileSymbol::SetFileName()
  850. {
  851.     PathSymbol *path_symbol = this -> PathSym();
  852.     char *directory_name = directory_symbol -> DirectoryName();
  853.     size_t directory_name_length = directory_symbol -> DirectoryNameLength();
  854.     bool dot_directory = (strcmp(directory_name, StringConstant::U8S__DO) == 0);
  855.     this -> file_name_length = (dot_directory ? 0 : directory_name_length) +
  856.                                this -> Utf8NameLength()   +
  857.                                (path_symbol -> IsZip() // For zip files, we need "()"; for regular directory, we need 1 '/'
  858.                                              ? 2
  859.                                              : (dot_directory || directory_name[directory_name_length - 1] == U_SLASH ? 0 : 1)) +
  860.                                (kind == JAVA ? java_suffix_length : class_suffix_length);
  861.  
  862.     file_name = new char[file_name_length + 1]; // +1 for '\0'
  863.     if (dot_directory)
  864.          file_name[0] = U_NULL;
  865.     else
  866.     {
  867.         strcpy(file_name, directory_symbol -> DirectoryName());
  868.         if (path_symbol -> IsZip())
  869.              strcat(file_name, StringConstant::U8S__LP);
  870.         else if (directory_name[directory_name_length - 1] != U_SLASH)
  871.              strcat(file_name, StringConstant::U8S__SL);
  872.     }
  873.     strcat(file_name, this -> Utf8Name());
  874.     strcat(file_name, kind == JAVA ? FileSymbol::java_suffix : FileSymbol::class_suffix);
  875.     if (path_symbol -> IsZip())
  876.         strcat(file_name, StringConstant::U8S__RP);
  877.  
  878.     assert(strlen(this -> file_name) == this -> file_name_length);
  879.  
  880.     return;
  881. }
  882.  
  883.  
  884. void FileSymbol::SetFileNameLiteral(Control *control)
  885. {
  886.     if (! file_name_literal)
  887.     {
  888.         char *file_name = FileName();
  889.  
  890.         int i;
  891.         for (i = FileNameLength() - 1; i >= 0; i--)
  892.         {
  893.             if (file_name[i] == U_SLASH)
  894.                 break;
  895.         }
  896.  
  897.         int file_name_start = i + 1,
  898.             file_name_length = FileNameLength() - file_name_start;
  899.         file_name_literal = control -> Utf8_pool.FindOrInsert(file_name + file_name_start, file_name_length);
  900.     }
  901.  
  902.     return;
  903. }
  904.  
  905.  
  906. void FileSymbol::CleanUp()
  907. {
  908.     delete lex_stream;
  909.     lex_stream = NULL;
  910.  
  911.     if (compilation_unit)
  912.     {
  913.         delete compilation_unit -> ast_pool;
  914.         compilation_unit = NULL;
  915.     }
  916.  
  917.     delete semantic;
  918.     semantic = NULL;
  919.  
  920.     return;
  921. }
  922.  
  923.  
  924. void TypeSymbol::SetClassName()
  925. {
  926.     size_t length;
  927.  
  928.     if (semantic_environment -> sem -> control.option.directory)
  929.     {
  930.         DirectorySymbol *output_directory = file_symbol -> OutputDirectory();
  931.         int directory_length = output_directory -> DirectoryNameLength();
  932.         char *directory_name = output_directory -> DirectoryName();
  933.         length = directory_length + this -> ExternalUtf8NameLength() + FileSymbol::class_suffix_length + 1; // +1 for /
  934.         class_name = new char[length + 1]; // +1 for '\0'
  935.  
  936.         strcpy(class_name, directory_name);
  937.  
  938.         if (directory_name[directory_length - 1] != U_SLASH)
  939.             strcat(class_name, StringConstant::U8S__SL);
  940.     }
  941.     else
  942.     {
  943.         char *file_name = semantic_environment -> sem -> lex_stream -> FileName();
  944.         int n;
  945.         for (n = semantic_environment -> sem -> lex_stream -> FileNameLength() - 1; n >= 0; n--)
  946.         {
  947.             if (file_name[n] == U_SLASH)
  948.                 break;
  949.         }
  950.         n++;
  951.  
  952.         length = n + this -> ExternalUtf8NameLength() + FileSymbol::class_suffix_length;
  953.         class_name = new char[length + 1]; // +1 for '\0'
  954.         strncpy(class_name, file_name, n);
  955.         class_name[n] = U_NULL;
  956.     }
  957.  
  958.     strcat(class_name, ExternalUtf8Name());
  959.     strcat(class_name, FileSymbol::class_suffix);
  960.  
  961.     assert(strlen(this -> class_name) <= length);
  962.  
  963.     return;
  964. }
  965.  
  966.  
  967. void TypeSymbol::ProcessNestedTypeSignatures(Semantic *sem, LexStream::TokenIndex tok)
  968. {
  969.     for (int i = 0; i < NumNestedTypeSignatures(); i++)
  970.     {
  971.         NameSymbol *name_symbol = sem -> control.ConvertUtf8ToUnicode(NestedTypeSignature(i), strlen(NestedTypeSignature(i)));
  972.         delete [] NestedTypeSignature(i);
  973.         sem -> ProcessNestedType(this, name_symbol, tok);
  974.     }
  975.  
  976.     delete nested_type_signatures;
  977.     nested_type_signatures = NULL;
  978.  
  979.     return;
  980. }
  981.  
  982.  
  983. void MethodSymbol::ProcessMethodThrows(Semantic *sem, LexStream::TokenIndex tok)
  984. {
  985.     if (throws_signatures)
  986.     {
  987.         assert(sem);
  988.  
  989.         //
  990.         // Process throws clause
  991.         //
  992.         for (int i = 0; i < NumThrowsSignatures(); i++)
  993.         {
  994.             TypeSymbol *type = sem -> ReadTypeFromSignature(this -> containing_type,
  995.                                                             ThrowsSignature(i),
  996.                                                             strlen(ThrowsSignature(i)),
  997.                                                             tok);
  998.             this -> AddThrows(type);
  999.             delete [] ThrowsSignature(i);
  1000.         }
  1001.  
  1002.         delete throws_signatures;
  1003.         throws_signatures = NULL;
  1004.     }
  1005.  
  1006.     return;
  1007. }
  1008.  
  1009.  
  1010. void MethodSymbol::SetSignature(Control &control, VariableSymbol *this0_variable)
  1011. {
  1012.     int len = 2 + strlen(this -> Type() -> SignatureString()); // +1 for '(' +1 for ')'
  1013.  
  1014.     if (this0_variable)
  1015.         len += strlen(this0_variable -> Type() -> SignatureString());
  1016.     for (int i = 0; i < this -> NumFormalParameters(); i++)
  1017.     {
  1018.         TypeSymbol *formal_type = this -> FormalParameter(i) -> Type();
  1019.         len += strlen(formal_type -> SignatureString());
  1020.     }
  1021.  
  1022.     char *method_signature = new char[len + 1]; // +1 for '\0'
  1023.     method_signature[0] = U_LEFT_PARENTHESIS;
  1024.     int k = 1;
  1025.     if (this0_variable)
  1026.     {
  1027.         for (char *str = this0_variable -> Type() -> SignatureString(); *str; str++, k++)
  1028.             method_signature[k] = *str;
  1029.     }
  1030.     for (int j = 0; j < this -> NumFormalParameters(); j++)
  1031.     {
  1032.         TypeSymbol *formal_type = this -> FormalParameter(j) -> Type();
  1033.         for (char *str = formal_type -> SignatureString(); *str; str++, k++)
  1034.             method_signature[k] = *str;
  1035.     }
  1036.     method_signature[k++] = U_RIGHT_PARENTHESIS;
  1037.     for (char *str = this -> Type() -> SignatureString(); *str; str++, k++)
  1038.          method_signature[k] = *str;
  1039.     method_signature[k] = U_NULL;
  1040.  
  1041.     this -> signature = control.Utf8_pool.FindOrInsert(method_signature, len);
  1042.  
  1043.     delete [] method_signature;
  1044.  
  1045.     return;
  1046. }
  1047.  
  1048.  
  1049. void MethodSymbol::ProcessMethodSignature(Semantic *sem, LexStream::TokenIndex token_location)
  1050. {
  1051.     if (! this -> type_)
  1052.     {
  1053.         assert(sem);
  1054.  
  1055.         int num_parameters = 0;
  1056.         char *signature = this -> SignatureString();
  1057.         signature++; // +1 to skip initial '('
  1058.  
  1059.         //
  1060.         // For the constructor of an inner type, skip the "this$0" argument.
  1061.         //
  1062.         if (this -> containing_type -> IsInner() && this -> Identity() == sem -> control.init_name_symbol)
  1063.         {
  1064.             if (*signature != U_RIGHT_PARENTHESIS)
  1065.             {
  1066.                 //
  1067.                 // Move to next signature
  1068.                 //
  1069.                 char *str;
  1070.                 for (str = signature; *str == U_LEFT_BRACKET; str++)
  1071.                     ;
  1072.                 if (*str == U_L)
  1073.                 {
  1074.                     for (str++; *str != U_SEMICOLON; str++)
  1075.                         ;
  1076.                 }
  1077.  
  1078.                 int len = str - signature + 1;
  1079.                 signature += len; // make signature point to next type
  1080.             }
  1081.         }
  1082.  
  1083.         while (*signature != U_RIGHT_PARENTHESIS)
  1084.         {
  1085.             //
  1086.             // Make up a name for each parameter... Recall that for an inner class we need to skip the this$0 parameter
  1087.             //
  1088.             NameSymbol *name_symbol = sem -> control.MakeParameter(++num_parameters);
  1089.             VariableSymbol *symbol = new VariableSymbol(name_symbol);
  1090.             symbol -> SetType(sem -> ProcessSignature(this -> containing_type, signature, token_location));
  1091.             symbol -> MarkComplete();
  1092.             this -> AddFormalParameter(symbol);
  1093.  
  1094.             //
  1095.             // Move to next signature
  1096.             //
  1097.             char *str;
  1098.             for (str = signature; *str == U_LEFT_BRACKET; str++)
  1099.                 ;
  1100.             if (*str == U_L)
  1101.             {
  1102.                 for (str++; *str != U_SEMICOLON; str++)
  1103.                     ;
  1104.             }
  1105.  
  1106.             int len = str - signature + 1;
  1107.             signature += len; // make signature point to next type
  1108.         }
  1109.         signature++; // skip L')'
  1110.  
  1111.         //
  1112.         // Now set the type of the method.
  1113.         //
  1114.         this -> SetType(sem -> ProcessSignature(this -> containing_type, signature, token_location));
  1115.  
  1116.         //
  1117.         // Create a symbol table for this method for consistency... and in order
  1118.         // to release the space used by the variable paramaters later.
  1119.         //
  1120.         BlockSymbol *block_symbol = new BlockSymbol(num_parameters);
  1121.         for (int k = 0; k < num_parameters; k++)
  1122.             block_symbol -> InsertVariableSymbol((*this -> formal_parameters)[k]);
  1123.         block_symbol -> CompressSpace(); // space optimization
  1124.         this -> SetBlockSymbol(block_symbol);
  1125.     }
  1126.  
  1127.     return;
  1128. }
  1129.  
  1130.  
  1131. void MethodSymbol::CleanUp()
  1132. {
  1133.     BlockSymbol *block_symbol = new BlockSymbol(this -> NumFormalParameters());
  1134.  
  1135.     //
  1136.     // Make a copy of each parameter into the new pared-down symbol table and
  1137.     // fix the FormalParameter information to identify the new symbol.
  1138.     //
  1139.     for (int k = 0; k < this -> NumFormalParameters(); k++)
  1140.     {
  1141.         VariableSymbol *formal_parameter = (*formal_parameters)[k],
  1142.                        *symbol = block_symbol -> InsertVariableSymbol(formal_parameter -> Identity());
  1143.         symbol -> SetType(formal_parameter -> Type());
  1144.         symbol -> MarkComplete();
  1145.         (*formal_parameters)[k] = symbol;
  1146.     }
  1147.  
  1148.     //
  1149.     // Destroy the old symbol and replace it by the new one.
  1150.     //
  1151.     delete this -> block_symbol;
  1152.     block_symbol -> CompressSpace(); // space optimization
  1153.     this -> SetBlockSymbol(block_symbol);
  1154.  
  1155.     this -> method_or_constructor_declaration = NULL; // remove reference to Ast structure
  1156.  
  1157.     return;
  1158. }
  1159.  
  1160.  
  1161. void VariableSymbol::ProcessVariableSignature(Semantic *sem, LexStream::TokenIndex token_location)
  1162. {
  1163.     if (! this -> type_)
  1164.     {
  1165.         assert(sem);
  1166.  
  1167.         this -> SetType(sem -> ProcessSignature((TypeSymbol *) owner, signature_string, token_location));
  1168.     }
  1169.  
  1170.     return;
  1171. }
  1172.  
  1173.  
  1174. bool TypeSymbol::IsNestedIn(TypeSymbol *type)
  1175. {
  1176.     for (SemanticEnvironment *env = this -> semantic_environment; env != NULL; env = env -> previous)
  1177.     {
  1178.         if (env -> Type() == type)
  1179.              return true;
  1180.     }
  1181.  
  1182.     return false;
  1183. }
  1184.  
  1185.  
  1186. bool TypeSymbol::CanAccess(TypeSymbol *type)
  1187. {
  1188.     assert(semantic_environment);
  1189.  
  1190.     SemanticEnvironment *env = this -> semantic_environment;
  1191.     //
  1192.     // Note that this case is only possible in the current environment (i.e., it is not recursively applicable)
  1193.     // as it is not possible to declare an inner class (even an anonymous one) within an explicit
  1194.     // constructor invocation. This is the case precisely because of the unavailability of the "this"
  1195.     // which one would need to pass to the inner class in question. See comment below...
  1196.     //
  1197.     if (env -> explicit_constructor_invocation && env -> explicit_constructor_invocation -> SuperCallCast())
  1198.     {
  1199.         //
  1200.         // If we are processing a super call statement in the constructor of an inner class then
  1201.         // we have access to the this$0 (passed to the constructor of the inner class as parameter) but
  1202.         // not to the "this" of the inner class in question, unless it is static.
  1203.         //
  1204.         if (this -> IsSubclass(type))
  1205.             return this -> ACC_STATIC(); // "this" class is accessible only if it is static.
  1206.         if (this -> IsInner())
  1207.         {
  1208.             if (this -> ContainingType() -> IsSubclass(type))
  1209.                 return true;
  1210.             env = env -> previous; // skip "this" type.
  1211.         }
  1212.     }
  1213.  
  1214.     for (; env != NULL; env = env -> previous)
  1215.     {
  1216.         if (env -> StaticRegion()) // are we in a static environment?
  1217.              break;
  1218.         else if (env -> Type() -> IsSubclass(type)) // then, check if we reached the type in question or one of its superclasses;
  1219.              return true;
  1220.         else if (env -> Type() -> ACC_STATIC())     // next, check whether or not the current type is static...
  1221.              break;
  1222.     }
  1223.  
  1224.     return false;
  1225. }
  1226.  
  1227.  
  1228. //
  1229. // Given two types T and T2 in different packages, the type T has protected
  1230. // access to T2 iff T or any class in which T is lexically enclosed is a subclass
  1231. // of T2 or of some other type T3 that lexically encloses T2.
  1232. //
  1233. // Of course, T2 and all its enclosing classes, if any, must have been declared
  1234. // either public or protected, otherwise they could not be eligible as a superclass
  1235. // candidate. We do not (and need not) check for that condition here.
  1236. //
  1237. bool TypeSymbol::HasProtectedAccessTo(TypeSymbol *target_type)
  1238. {
  1239.     assert(semantic_environment);
  1240.  
  1241.     for (SemanticEnvironment *env = this -> semantic_environment; env != NULL; env = env -> previous)
  1242.     {
  1243.         TypeSymbol *main_type = env -> Type();
  1244.         for (TypeSymbol *type = target_type; type; type = type -> owner -> TypeCast())
  1245.         {
  1246.             if (main_type -> IsSubclass(type)) // then, check if we reached the type in question or one of its superclasses;
  1247.                 return true;
  1248.         }
  1249.     }
  1250.  
  1251.     return false;
  1252. }
  1253.  
  1254.  
  1255. inline NameSymbol *TypeSymbol::GetThisName(Control &control, int n)
  1256. {
  1257.     IntToWstring value(n);
  1258.  
  1259.     int length = wcslen(StringConstant::US__this_DOLLAR) + value.Length();
  1260.     wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1261.     wcscpy(name, StringConstant::US__this_DOLLAR);
  1262.     wcscat(name, value.String());
  1263.     NameSymbol *name_symbol = control.FindOrInsertName(name, length);
  1264.  
  1265.     delete [] name;
  1266.  
  1267.     return name_symbol;
  1268. }
  1269.  
  1270.  
  1271. VariableSymbol *TypeSymbol::InsertThis(int n)
  1272. {
  1273.     assert(IsInner());
  1274.  
  1275.     Control &control = semantic_environment -> sem -> control;
  1276.     VariableSymbol *variable_symbol = NULL;
  1277.  
  1278.     if (n == 0)
  1279.     {
  1280.         assert(NumConstructorParameters() == 0); // no local shadows and no this$0 !!!
  1281.         assert(NumEnclosingInstances() == 0);
  1282.  
  1283.         //
  1284.         // Create a this0 pointer for an inner class.
  1285.         //
  1286.         variable_symbol = InsertVariableSymbol(control.this0_name_symbol);
  1287.         variable_symbol -> MarkSynthetic();
  1288.         variable_symbol -> SetType(ContainingType());
  1289.         variable_symbol -> SetACC_PRIVATE();
  1290. //        variable_symbol -> SetACC_FINAL();
  1291.         variable_symbol -> SetOwner((TypeSymbol *) this);
  1292.         variable_symbol -> MarkComplete();
  1293.  
  1294.         AddConstructorParameter(variable_symbol);
  1295.         AddEnclosingInstance(variable_symbol); // must at least have this$0
  1296.     }
  1297.     else
  1298.     {
  1299.         assert(NumEnclosingInstances() == n);
  1300.  
  1301.         //
  1302.         // Create a this$n pointer.
  1303.         //
  1304.         variable_symbol = InsertVariableSymbol(GetThisName(control, n));
  1305.         variable_symbol -> MarkSynthetic();
  1306.         variable_symbol -> SetType(EnclosingInstance(n - 1) -> Type() -> ContainingType());
  1307.         variable_symbol -> SetACC_PRIVATE();
  1308. //        variable_symbol -> SetACC_FINAL();
  1309.         variable_symbol -> SetOwner((TypeSymbol *) this);
  1310.         variable_symbol -> MarkComplete();
  1311.  
  1312.         AddEnclosingInstance(variable_symbol);
  1313.     }
  1314.  
  1315.     return variable_symbol;
  1316. }
  1317.  
  1318.  
  1319. TypeSymbol *TypeSymbol::FindOrInsertClassLiteralClass(LexStream::TokenIndex tok)
  1320. {
  1321.     Semantic *sem = semantic_environment -> sem;
  1322.     AstCompilationUnit *compilation_unit = sem -> compilation_unit;
  1323.     Control &control = sem -> control;
  1324.  
  1325.     assert(this == outermost_type && this -> ACC_INTERFACE());
  1326.  
  1327.     if (! this -> class_literal_class)
  1328.     {
  1329.         AstClassInstanceCreationExpression *class_creation = compilation_unit -> ast_pool -> GenClassInstanceCreationExpression();
  1330.         class_creation -> base_opt      = NULL;
  1331.         class_creation -> dot_token_opt = 0;
  1332.         class_creation -> new_token = tok;
  1333.  
  1334.              AstSimpleName *ast_type = compilation_unit -> ast_pool -> GenSimpleName(tok);
  1335.  
  1336.         class_creation -> class_type = compilation_unit -> ast_pool -> GenTypeExpression(ast_type);
  1337.         class_creation -> left_parenthesis_token  = tok;
  1338.         class_creation -> right_parenthesis_token = tok;
  1339.  
  1340.             AstClassBody *class_body = compilation_unit -> ast_pool -> GenClassBody();
  1341.             class_body -> left_brace_token = tok;
  1342.             class_body -> right_brace_token = tok;
  1343.  
  1344.         class_creation -> class_body_opt = class_body;
  1345.  
  1346.         TypeSymbol *class_literal_type = sem -> GetAnonymousType(class_creation, control.Object());
  1347.         (void) class_literal_type -> FindOrInsertClassLiteralMethod(control);
  1348.  
  1349.         sem -> AddDependence(class_literal_type, control.Class(), tok);
  1350.  
  1351.         this -> class_literal_class = class_literal_type;
  1352.     }
  1353.  
  1354.     return this -> class_literal_class;
  1355. }
  1356.  
  1357.  
  1358. MethodSymbol *TypeSymbol::FindOrInsertClassLiteralMethod(Control &control)
  1359. {
  1360.     if (! class_literal_method)
  1361.     {
  1362.         //
  1363.         // Note that max_variable_index is initialized to 1 (instead of 0),
  1364.         // even though the class literal method is static. The reason is that
  1365.         // in generating code for this method, a try statement with a catch
  1366.         // will be used. Therefore, an extra "local" slot is required for the
  1367.         // local Exception parameter of the catch clause.
  1368.         //
  1369.         BlockSymbol *block_symbol = new BlockSymbol(1); // the associated symbol table will contain 1 element
  1370.         block_symbol -> max_variable_index = 1;
  1371.  
  1372.         class_literal_method = InsertMethodSymbol(control.class_name_symbol);
  1373.         class_literal_method -> MarkSynthetic();
  1374.         class_literal_method -> SetType(control.Class());
  1375.         class_literal_method -> SetACC_STATIC();
  1376.         class_literal_method -> SetContainingType((TypeSymbol *) this);
  1377.         class_literal_method -> SetBlockSymbol(block_symbol);
  1378.  
  1379.             VariableSymbol *variable_symbol = block_symbol -> InsertVariableSymbol(control.MakeParameter(1));
  1380.             variable_symbol -> MarkSynthetic();
  1381.             variable_symbol -> SetType(control.String());
  1382.             variable_symbol -> SetOwner(class_literal_method);
  1383.             variable_symbol -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1384.  
  1385.         class_literal_method -> AddFormalParameter(variable_symbol);
  1386.         class_literal_method -> SetSignature(control);
  1387.     }
  1388.  
  1389.     return class_literal_method;
  1390. }
  1391.  
  1392.  
  1393. Utf8LiteralValue *TypeSymbol::FindOrInsertClassLiteralName(Control &control)
  1394. {
  1395.     if (! class_literal_name)
  1396.     {
  1397.         int length = fully_qualified_name -> length;
  1398.         char *slashed_name = fully_qualified_name -> value;
  1399.         char *name = new char[length + 1];
  1400.         for (int i = 0; i < length; i++)
  1401.             name[i] = (slashed_name[i] == U_SLASH ? (wchar_t) U_DOT : slashed_name[i]);
  1402.         name[length] = U_NULL;
  1403.         class_literal_name = control.Utf8_pool.FindOrInsert(name, length);
  1404.         delete [] name;
  1405.     }
  1406.  
  1407.     return class_literal_name;
  1408. }
  1409.  
  1410.  
  1411. VariableSymbol *TypeSymbol::FindOrInsertClassLiteral(TypeSymbol *type)
  1412. {
  1413.     assert(IsTopLevel() && (! type -> Primitive()));
  1414.  
  1415.     Semantic *sem = semantic_environment -> sem;
  1416.     Control &control = sem -> control;
  1417.  
  1418.     (void) this -> FindOrInsertClassLiteralMethod(control);
  1419.  
  1420.     (void) type -> FindOrInsertClassLiteralName(control);
  1421.  
  1422.     NameSymbol *name_symbol = NULL;
  1423.     char *signature = type -> SignatureString();
  1424.     if (signature[0] == U_LEFT_BRACKET) // an array?
  1425.     {
  1426.         int array_length = wcslen(StringConstant::US__array),
  1427.             length = strlen(signature) + array_length;
  1428.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1429.         wcscpy(name, StringConstant::US__array);
  1430.         int i,
  1431.             k;
  1432.         for (i = 0, k = array_length; signature[i] == U_LEFT_BRACKET; i++, k++)
  1433.             name[k] = U_DOLLAR;
  1434.         for (wchar_t ch = signature[i++]; ch && ch != U_SEMICOLON; ch = signature[i++])
  1435.             name[k++] = (ch == U_SLASH ? (wchar_t) U_DOLLAR : ch);
  1436.         name[k] = U_NULL;
  1437.         name_symbol = control.FindOrInsertName(name, k);
  1438.  
  1439.         delete [] name;
  1440.     }
  1441.     else if (signature[0] == U_L) // a reference type ?
  1442.     {
  1443.         int class_length = wcslen(StringConstant::US__class_DOLLAR),
  1444.             length = strlen(signature) + class_length;
  1445.  
  1446.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1447.         wcscpy(name, StringConstant::US__class_DOLLAR);
  1448.         int i = 0,
  1449.             k = class_length;
  1450.         for (wchar_t ch = signature[i++]; ch && ch != U_SEMICOLON; ch = signature[i++])
  1451.             name[k++] = (ch == U_SLASH ? (wchar_t) U_DOLLAR : ch);
  1452.         name[k] = U_NULL;
  1453.         name_symbol = control.FindOrInsertName(name, k);
  1454.  
  1455.         delete [] name;
  1456.     }
  1457.  
  1458.     VariableSymbol *variable_symbol = FindVariableSymbol(name_symbol);
  1459.     if (! variable_symbol)
  1460.     {
  1461.         variable_symbol = InsertVariableSymbol(name_symbol);
  1462.         variable_symbol -> MarkSynthetic();
  1463.         variable_symbol -> SetType(control.Class());
  1464.         variable_symbol -> SetACC_PRIVATE();
  1465.         variable_symbol -> SetACC_STATIC();
  1466.         variable_symbol -> SetOwner((TypeSymbol *) this);
  1467.         variable_symbol -> MarkComplete();
  1468.  
  1469.         AddClassLiteral(variable_symbol);
  1470.     }
  1471.  
  1472.     return variable_symbol;
  1473. }
  1474.  
  1475.  
  1476. VariableSymbol *TypeSymbol::FindOrInsertLocalShadow(VariableSymbol *local)
  1477. {
  1478.     assert(this -> IsLocal());
  1479.  
  1480.     Control &control = semantic_environment -> sem -> control;
  1481.     VariableSymbol *variable = (VariableSymbol *) (local_shadow_map ? local_shadow_map -> Image(local) : NULL);
  1482.  
  1483.     //
  1484.     // For a local class, if it does not yet have a shadow for a local variable
  1485.     // that it needs access to, create one.
  1486.     //
  1487.     // Note that since this function is always invoked after the symbol
  1488.     // table for the type in question has been extended, the local shadow will
  1489.     // not appear in the expanded_field_table. Creating a shadow in the
  1490.     // expanded_field_table as well would cut down on the number of calls to
  1491.     // this function. However, the reason why we don't create such a shadow is
  1492.     // that since the new symbol is assigned a new name on the fly, its
  1493.     // name_symbol will fall outside the range of the expanded field table in
  1494.     // question.
  1495.     //
  1496.     if (! variable)
  1497.     {
  1498.         int length = 4 + local -> NameLength(); // +4 for val$
  1499.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1500.         wcscpy(name, StringConstant::US__val_DOLLAR);
  1501.         wcscat(name, local -> Name());
  1502.         NameSymbol *name_symbol = control.FindOrInsertName(name, length);
  1503.  
  1504.         variable = InsertVariableSymbol(name_symbol);
  1505.         variable -> MarkSynthetic();
  1506.         variable -> accessed_local = local;
  1507.         variable -> SetType(local -> Type());
  1508.         variable -> SetACC_PRIVATE();
  1509. //        variable -> SetACC_FINAL();
  1510.         variable -> SetOwner((TypeSymbol *) this);
  1511.         variable -> MarkComplete();
  1512.  
  1513.         AddConstructorParameter(variable);
  1514.  
  1515.         delete [] name;
  1516.  
  1517.         for (int i = 0; i < NumGeneratedConstructors(); i++)
  1518.         {
  1519.             MethodSymbol *constructor = GeneratedConstructor(i);
  1520.  
  1521.             VariableSymbol *symbol = constructor -> block_symbol -> InsertVariableSymbol(name_symbol);
  1522.             symbol -> MarkSynthetic();
  1523.             symbol -> SetType(variable -> Type());
  1524.             symbol -> SetOwner(constructor);
  1525.             symbol -> SetLocalVariableIndex(constructor -> block_symbol -> max_variable_index++);
  1526.             if (control.IsDoubleWordType(symbol -> Type()))
  1527.                 constructor -> block_symbol -> max_variable_index++;
  1528.             constructor -> AddFormalParameter(symbol);
  1529.         }
  1530.  
  1531.         if (! local_shadow_map)
  1532.             local_shadow_map = new SymbolMap();
  1533.         local_shadow_map -> Map(local, variable);
  1534.     }
  1535.  
  1536. assert(variable -> accessed_local == local);
  1537.  
  1538.     return variable;
  1539. }
  1540.  
  1541.  
  1542. inline void TypeSymbol::MapSymbolToReadMethod(Symbol *symbol, MethodSymbol *method)
  1543. {
  1544.     if (! read_method)
  1545.         read_method = new SymbolMap();
  1546.     read_method -> Map(symbol, method);
  1547.  
  1548.     return;
  1549. }
  1550.  
  1551. inline MethodSymbol *TypeSymbol::ReadMethod(Symbol *symbol)
  1552. {
  1553.     return (MethodSymbol *) (read_method ? read_method -> Image(symbol) : NULL);
  1554. }
  1555.  
  1556. inline void TypeSymbol::MapSymbolToWriteMethod(VariableSymbol *symbol, MethodSymbol *method)
  1557. {
  1558.     if (! write_method)
  1559.         write_method = new SymbolMap();
  1560.     write_method -> Map(symbol, method);
  1561.  
  1562.     return;
  1563. }
  1564.  
  1565. inline MethodSymbol *TypeSymbol::WriteMethod(VariableSymbol *symbol)
  1566. {
  1567.     return (MethodSymbol *) (write_method ? write_method -> Image(symbol) : NULL);
  1568. }
  1569.  
  1570. MethodSymbol *TypeSymbol::GetReadAccessMethod(MethodSymbol *member)
  1571. {
  1572.     TypeSymbol *this_type = (TypeSymbol *) this,
  1573.                *containing_type = member -> containing_type;
  1574.  
  1575.     assert((member -> ACC_PRIVATE() && this_type == containing_type) || (member -> ACC_PROTECTED() && this_type != containing_type));
  1576.  
  1577.     MethodSymbol *read_method = this_type -> ReadMethod(member);
  1578.  
  1579.     if (! read_method)
  1580.     {
  1581.         Semantic *sem = this_type -> semantic_environment -> sem;
  1582.  
  1583.         assert(sem);
  1584.  
  1585.         Control &control = sem -> control;
  1586.         StoragePool *ast_pool = sem -> compilation_unit -> ast_pool;
  1587.  
  1588.         IntToWstring value(member -> Identity() == control.init_name_symbol ? this_type -> NumPrivateAccessConstructors()
  1589.                                                                             : this_type -> NumPrivateAccessMethods());
  1590.  
  1591.         int length = 7 + value.Length(); // +7 for access$
  1592.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1593.         wcscpy(name, StringConstant::US__access_DOLLAR);
  1594.         wcscat(name, value.String());
  1595.  
  1596.         BlockSymbol *block_symbol = new BlockSymbol(member -> NumFormalParameters() + 3);
  1597.  
  1598.         read_method = this_type -> InsertMethodSymbol(control.FindOrInsertName(name, length));
  1599.         read_method -> MarkSynthetic();
  1600.         read_method -> SetType(member -> Type());
  1601.         read_method -> SetContainingType(this_type);
  1602.         read_method -> SetBlockSymbol(block_symbol);
  1603.  
  1604.         for (int i = 0; i < member -> NumThrows(); i++)
  1605.             read_method -> AddThrows(member -> Throws(i));
  1606.  
  1607.         //
  1608.         //
  1609.         //
  1610.         if (member -> Identity() != control.init_name_symbol) // not a constructor
  1611.         {
  1612.             read_method -> SetACC_STATIC();
  1613.             block_symbol -> max_variable_index = 0;
  1614.  
  1615.             if (! member -> ACC_STATIC())
  1616.             {
  1617.                 VariableSymbol *instance = block_symbol -> InsertVariableSymbol(control.MakeParameter(1));
  1618.                 instance -> MarkSynthetic();
  1619.                 instance -> SetType(this_type);
  1620.                 instance -> SetOwner(read_method);
  1621.                 instance -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1622.                 read_method -> AddFormalParameter(instance);
  1623.             }
  1624.  
  1625.             for (int i = 0; i < member -> NumFormalParameters(); i++)
  1626.             {
  1627.                 VariableSymbol *parm = block_symbol -> InsertVariableSymbol(member -> FormalParameter(i) -> Identity());
  1628.                 parm -> MarkSynthetic();
  1629.                 parm -> SetType(member -> FormalParameter(i) -> Type());
  1630.                 parm -> SetOwner(read_method);
  1631.                 parm -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1632.                 if (control.IsDoubleWordType(parm -> Type()))
  1633.                     block_symbol -> max_variable_index++;
  1634.                 read_method -> AddFormalParameter(parm);
  1635.             }
  1636.             read_method -> SetSignature(control);
  1637.             // A read access method has no throws clause !
  1638.  
  1639.             this_type -> AddPrivateAccessMethod(read_method);
  1640.         }
  1641.         else
  1642.         {
  1643.             //
  1644.             // A constructor in a local class already has a "LocalConstructor()" associated
  1645.             // with it that can be used as a read access method.
  1646.             //
  1647.             assert(! this_type -> IsLocal());
  1648.  
  1649.             //
  1650.             //
  1651.             //
  1652.             block_symbol -> max_variable_index = 1;
  1653.             read_method -> SetExternalIdentity(member -> Identity());
  1654.  
  1655.             Ast *declaration = member -> method_or_constructor_declaration;
  1656.             AstMethodDeclaration *method_declaration = declaration -> MethodDeclarationCast();
  1657.             AstMethodDeclarator *declarator = (method_declaration
  1658.                                                      ? method_declaration -> method_declarator
  1659.                                                      : ((AstConstructorDeclaration *) declaration) -> constructor_declarator);
  1660.             LexStream::TokenIndex loc = declarator -> identifier_token;
  1661.  
  1662.             //
  1663.             // Create a new anonymous type in order to create a unique substitute constructor.
  1664.             //
  1665.             AstClassInstanceCreationExpression *class_creation = ast_pool -> GenClassInstanceCreationExpression();
  1666.             class_creation -> base_opt      = NULL;
  1667.             class_creation -> dot_token_opt = 0;
  1668.             class_creation -> new_token = loc;
  1669.  
  1670.                 AstSimpleName *ast_type = ast_pool -> GenSimpleName(loc);
  1671.  
  1672.             class_creation -> class_type = ast_pool -> GenTypeExpression(ast_type);
  1673.             class_creation -> left_parenthesis_token  = loc;
  1674.             class_creation -> right_parenthesis_token = loc;
  1675.  
  1676.                 AstClassBody *class_body = ast_pool -> GenClassBody();
  1677.                 class_body -> left_brace_token = loc;
  1678.                 class_body -> right_brace_token = loc;
  1679.  
  1680.             class_creation -> class_body_opt = class_body;
  1681.  
  1682.             TypeSymbol *anonymous_type = sem -> GetAnonymousType(class_creation, control.Object());
  1683.  
  1684.             //
  1685.             //
  1686.             //
  1687.             AstMethodDeclarator *method_declarator       = ast_pool -> GenMethodDeclarator();
  1688.             method_declarator -> identifier_token        = loc;
  1689.             method_declarator -> left_parenthesis_token  = declarator -> LeftToken();
  1690.             method_declarator -> right_parenthesis_token = declarator -> RightToken();
  1691.  
  1692.             AstThisCall *this_call = ast_pool -> GenThisCall();
  1693.             this_call -> base_opt                = NULL;
  1694.             this_call -> this_token              = loc;
  1695.             this_call -> left_parenthesis_token  = loc;
  1696.             this_call -> right_parenthesis_token = loc;
  1697.             this_call -> semicolon_token         = loc;
  1698.             this_call -> symbol = member;
  1699.  
  1700.             VariableSymbol *this0_variable = NULL;
  1701.             if (this_type -> IsInner())
  1702.             {
  1703.                 this0_variable = block_symbol -> InsertVariableSymbol(control.this0_name_symbol);
  1704.                 this0_variable -> MarkSynthetic();
  1705.                 this0_variable -> SetType(this_type -> ContainingType());
  1706.                 this0_variable -> SetOwner(read_method);
  1707.                 this0_variable -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1708.             }
  1709.  
  1710.             //
  1711.             // Add extra parameter with anonymous type...
  1712.             //
  1713.             VariableSymbol *parm = block_symbol -> InsertVariableSymbol(control.MakeParameter(1));
  1714.             parm -> MarkSynthetic();
  1715.             parm -> SetType(anonymous_type);
  1716.             parm -> SetOwner(read_method);
  1717.             parm -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1718.             read_method -> AddFormalParameter(parm);
  1719.  
  1720.             //
  1721.             // Since private_access_constructors will be compiled (see body.cpp), we must create
  1722.             // valid ast_simple_names for its parameters.
  1723.             //
  1724.             for (int i = 0; i < member -> NumFormalParameters(); i++)
  1725.             {
  1726.                 parm = block_symbol -> InsertVariableSymbol(member -> FormalParameter(i) -> Identity());
  1727.                 parm -> MarkSynthetic();
  1728.                 parm -> SetType(member -> FormalParameter(i) -> Type());
  1729.                 parm -> SetOwner(read_method);
  1730.                 parm -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1731.                 if (control.IsDoubleWordType(parm -> Type()))
  1732.                     block_symbol -> max_variable_index++;
  1733.                 read_method -> AddFormalParameter(parm);
  1734.  
  1735.                 //
  1736.                 // Since private_access_constructors will be compiled (see body.cpp), we must create
  1737.                 // valid ast_simple_names for its parameters.
  1738.                 //
  1739.                 AstVariableDeclaratorId *variable_declarator_name = declarator -> FormalParameter(i)
  1740.                                                                                -> formal_declarator -> variable_declarator_name;
  1741.                 AstSimpleName *simple_name = ast_pool -> GenSimpleName(variable_declarator_name -> identifier_token);
  1742.                 simple_name -> symbol = parm;
  1743.                 this_call -> AddArgument(simple_name);
  1744.             }
  1745.             read_method -> SetSignature(control, this0_variable);
  1746.             // A read access method has no throws clause !
  1747.  
  1748.             AstReturnStatement *return_statement = ast_pool -> GenReturnStatement();
  1749.             return_statement -> return_token = loc;
  1750.             return_statement -> expression_opt = NULL;
  1751.             return_statement -> semicolon_token = loc;
  1752.             return_statement -> is_reachable = true;
  1753.  
  1754.             AstBlock *block = ast_pool -> GenBlock();
  1755.             block -> AllocateBlockStatements(1); // this block contains one statement
  1756.             block -> left_brace_token  = loc;
  1757.             block -> right_brace_token = loc;
  1758.  
  1759.             block -> block_symbol = new BlockSymbol(0); // the symbol table associated with this block will contain no element
  1760.             block -> is_reachable = true;
  1761.             block -> can_complete_normally = false;
  1762.             block -> AddStatement(return_statement);
  1763.  
  1764.             AstConstructorBlock *constructor_block                   = ast_pool -> GenConstructorBlock();
  1765.             constructor_block -> left_brace_token                    = loc;
  1766.             constructor_block -> explicit_constructor_invocation_opt = this_call;
  1767.             constructor_block -> block                               = block;
  1768.             constructor_block -> right_brace_token                   = loc;
  1769.  
  1770.             AstConstructorDeclaration *constructor_declaration  = ast_pool -> GenConstructorDeclaration();
  1771.             constructor_declaration -> constructor_declarator   = method_declarator;
  1772.             constructor_declaration -> constructor_body         = constructor_block;
  1773.  
  1774.             constructor_declaration -> constructor_symbol = read_method;
  1775.             read_method -> method_or_constructor_declaration = constructor_declaration;
  1776.  
  1777.             this_type -> AddPrivateAccessConstructor(read_method);
  1778.         }
  1779.  
  1780.         read_method -> accessed_member = member;
  1781.         this_type -> MapSymbolToReadMethod(member, read_method);
  1782.  
  1783.         delete [] name;
  1784.     }
  1785.  
  1786.     return read_method;
  1787. }
  1788.  
  1789.  
  1790. MethodSymbol *TypeSymbol::GetReadAccessMethod(VariableSymbol *member)
  1791. {
  1792.     TypeSymbol *this_type = (TypeSymbol *) this,
  1793.                *containing_type = member -> owner -> TypeCast();
  1794.  
  1795.     assert((member -> ACC_PRIVATE() && this_type == containing_type) || (member -> ACC_PROTECTED() && this_type != containing_type));
  1796.  
  1797.  
  1798.     MethodSymbol *read_method = this_type -> ReadMethod(member);
  1799.  
  1800.     if (! read_method)
  1801.     {
  1802.         Semantic *sem = this_type -> semantic_environment -> sem;
  1803.  
  1804.         assert(sem);
  1805.  
  1806.         Control &control = sem -> control;
  1807.  
  1808.         IntToWstring value(this_type -> NumPrivateAccessMethods());
  1809.  
  1810.         int length = 7 + value.Length(); // +7 for access$
  1811.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1812.         wcscpy(name, StringConstant::US__access_DOLLAR);
  1813.         wcscat(name, value.String());
  1814.  
  1815.         read_method = this_type -> InsertMethodSymbol(control.FindOrInsertName(name, length));
  1816.         read_method -> MarkSynthetic();
  1817.         read_method -> SetType(member -> Type());
  1818.         read_method -> SetACC_STATIC();
  1819.         read_method -> SetContainingType(this_type);
  1820.  
  1821.         //
  1822.         // A read access method for a field has 1 formal parameter if the member in question is not static
  1823.         //
  1824.         BlockSymbol *block_symbol = new BlockSymbol(3);
  1825.         block_symbol -> max_variable_index = 0;
  1826.         read_method -> SetBlockSymbol(block_symbol);
  1827.  
  1828.         if (! member -> ACC_STATIC())
  1829.         {
  1830.             VariableSymbol *instance = block_symbol -> InsertVariableSymbol(control.MakeParameter(1));
  1831.             instance -> MarkSynthetic();
  1832.             instance -> SetType(this_type);
  1833.             instance -> SetOwner(read_method);
  1834.             instance -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1835.             read_method -> AddFormalParameter(instance);
  1836.         }
  1837.  
  1838.         read_method -> SetSignature(control);
  1839.         // A read access method has no throws clause !
  1840.  
  1841.         read_method -> accessed_member = member;
  1842.         this_type -> MapSymbolToReadMethod(member, read_method);
  1843.         this_type -> AddPrivateAccessMethod(read_method);
  1844.  
  1845.         delete [] name;
  1846.     }
  1847.  
  1848.     return read_method;
  1849. }
  1850.  
  1851.  
  1852. MethodSymbol *TypeSymbol::GetWriteAccessMethod(VariableSymbol *member)
  1853. {
  1854.     TypeSymbol *this_type = (TypeSymbol *) this,
  1855.                *containing_type = member -> owner -> TypeCast();
  1856.  
  1857.     assert((member -> ACC_PRIVATE() && this_type == containing_type) || (member -> ACC_PROTECTED() && this_type != containing_type));
  1858.  
  1859.     MethodSymbol *write_method = this_type -> WriteMethod(member);
  1860.  
  1861.     if (! write_method)
  1862.     {
  1863.         Semantic *sem = this_type -> semantic_environment -> sem;
  1864.  
  1865.         assert(sem);
  1866.  
  1867.         Control &control = sem -> control;
  1868.  
  1869.         IntToWstring value(this_type -> NumPrivateAccessMethods());
  1870.  
  1871.         int length = 7 + value.Length(); // +7 for access$
  1872.         wchar_t *name = new wchar_t[length + 1]; // +1 for '\0';
  1873.         wcscpy(name, StringConstant::US__access_DOLLAR);
  1874.         wcscat(name, value.String());
  1875.  
  1876.         write_method = this_type -> InsertMethodSymbol(control.FindOrInsertName(name, length));
  1877.         write_method -> MarkSynthetic();
  1878.         write_method -> SetType(sem -> control.void_type);
  1879.         write_method -> SetACC_STATIC();
  1880.         write_method -> SetContainingType(this_type);
  1881.  
  1882.         BlockSymbol *block_symbol = new BlockSymbol(3);
  1883.         block_symbol -> max_variable_index = 0;
  1884.         write_method -> SetBlockSymbol(block_symbol);
  1885.  
  1886.         //
  1887.         // A write access method takes one or two arguments. The first is the instance, $1,
  1888.         // of the object in which to do the writing if the member in question is not static.
  1889.         // The second is a parameter of the same type as the member. For a member named "m",
  1890.         // the body of the write access method will consist of the single statement:
  1891.         //
  1892.         //    $1.m = m;
  1893.         //
  1894.         if (! member -> ACC_STATIC())
  1895.         {
  1896.             VariableSymbol *instance = block_symbol -> InsertVariableSymbol(control.MakeParameter(1));
  1897.             instance -> MarkSynthetic();
  1898.             instance -> SetType(this_type);
  1899.             instance -> SetOwner(write_method);
  1900.             instance -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1901.             write_method -> AddFormalParameter(instance);
  1902.         }
  1903.  
  1904.         VariableSymbol *symbol = block_symbol -> InsertVariableSymbol(member -> Identity());
  1905.         symbol -> MarkSynthetic();
  1906.         symbol -> SetType(member -> Type());
  1907.         symbol -> SetLocalVariableIndex(block_symbol -> max_variable_index++);
  1908.         if (control.IsDoubleWordType(member -> Type()))
  1909.             block_symbol -> max_variable_index++;
  1910.         write_method -> AddFormalParameter(symbol);
  1911.  
  1912.         write_method -> SetSignature(control);
  1913.         // A write access method has no throws clause !
  1914.  
  1915.         write_method -> accessed_member = member;
  1916.         this_type -> MapSymbolToWriteMethod(member, write_method);
  1917.         this_type -> AddPrivateAccessMethod(write_method);
  1918.  
  1919.         delete [] name;
  1920.     }
  1921.  
  1922.     return write_method;
  1923. }
  1924.  
  1925.  
  1926.